Codex Model Speed Benchmark
先给结论
本文所有速度数字都来自 2026 年 8 月 12 日的一次本地实测,推理档位固定为 medium,每个 模型 × 服务层 组合重复 3 次。官方资料只用于确认模型定位和 streaming 支持,不提供或背书本文的速度数字。
| 模型 | Standard 流式 P50 | Fast 流式 P50 | Fast/Standard | 同 tier 模型差异 |
|---|---|---|---|---|
| GPT-5.6 Sol | 57.40 tok/s | 88.02 tok/s | 1.53× | 比 Luna 快 3.4%–5.6% |
| GPT-5.6 Luna | 55.52 tok/s | 83.36 tok/s | 1.50× | 比 Sol 慢 3.3%–5.3% |
服务层差异远大于模型差异。如果任务需要连续生成数千到数万 token,Fast 是本轮最稳定、最显著的速度变量;如果任务更看重能力或成本,单凭这张速度表仍不足以选模型。OpenAI 将 Sol 定位为复杂专业工作的旗舰模型,将 Luna 定位为成本敏感、高吞吐工作负载的模型,但本文没有评测答案质量,也没有把 API 标价换算成 Codex 订阅用量。
测试口径
为什么拆开测
一次 Codex 请求的端到端时间可以写成:
1 | T_e2e = T_client + T_queue + T_prefill + T_reasoning + T_stream + T_finish |
这里的 T_e2e 是从发起 turn 到完成的总时间;T_queue 是排队或调度等待;T_prefill 是输入处理;T_reasoning 是首段可见文本之前的隐藏推理;T_stream 是可见文本持续到达的阶段。客户端只能直接观察其中若干边界,不能从总秒数反推出服务端每一项的真实耗时。
长输出测试使用 Codex app-server 的 item/agentMessage/delta 事件。最终消息文本使用 o200k_base 独立计数,边界修正流式吞吐定义为:
1 | R_stream = (T_text - T_first_delta) / (t_last_delta - t_first_delta) |
T_text 是最终消息文本 token 数,T_first_delta 是第一个 delta 已经携带的 token 数。扣掉首 delta 是因为它在计时起点到达时已经生成。这个指标排除了首 token 前等待,但仍会受网络、服务端调度、批处理和流式节流影响,因而应称为客户端可观测流式文本吞吐,而不是服务端纯解码算力。
图中应重点看两个测量边界:左侧红色秒表停在首个文本 delta 到来之前,右侧橙色标尺只观察文本连续输出。TTFT(Time To First Token,首 token 延迟)与流式 tok/s 可以朝相反方向变化,所以 Fast 的持续输出更快,不自动等于每个请求的总等待都缩短相同比例。
如何保证可比
测试固定了以下条件:
- 同一客户端:
codex-cli 0.147.0-alpha.6.5。 - 同一模型档位:Sol 与 Luna 都使用
mediumreasoning effort。 - 同一服务层定义:Standard 不设置
service_tier;Fast 显式设置service_tier="priority"。 - 同一输出对象:结构化 JSON 中固定 909 行,每行 10 个
speed,目标至少 10,000 个最终消息文本 token。 - 同一执行方式:隔离临时工作目录、只读沙箱、禁止工具调用、串行运行,避免并发争抢速率额度。
- 同一统计方式:每组 3 次,报告 P50 和 P90,不以单次最快样本排名;失败与异常样本不删除。
10K 输出的单次命令形态如下,四组只改变 model 和 tier:
1 | PYTHONPATH=/tmp/codex-speed-benchmark-deps python3 codex_stream_benchmark.py \ |
每次实际输出为 10,003 或 10,093 个文本 token;12/12 次达到目标,12/12 次最终消息与 delta 拼接完全一致,输出测试缓存比例为 0%。因此,流式吞吐结果可以在本轮范围内直接比较。
10K 输出结果
流式吞吐
| 模型 | 模式 | 流式 tok/s P50 | 流式 tok/s P90 | 三次样本范围 |
|---|---|---|---|---|
| Sol | Standard | 57.40 | 60.08 | 56.56–60.74 |
| Sol | Fast | 88.02 | 88.45 | 86.12–88.56 |
| Luna | Standard | 55.52 | 55.56 | 54.77–55.57 |
| Luna | Fast | 83.36 | 83.36 | 83.26–83.36 |
Fast 的效果在三次长输出里相当稳定:Sol 的 P50 从 57.40 提升到 88.02 tok/s,Luna 从 55.52 提升到 83.36 tok/s。相反,模型间差异较小:Standard 下 Sol/Luna 为 1.034×,Fast 下为 1.056×。如果只讨论长文本持续输出,优先级应是先决定是否使用 Fast,再讨论 Sol 与 Luna 的几百分点差异。
端到端等待
端到端时间的结论没有流式吞吐那么整齐:
| 模型 | 模式 | 端到端 P50 | 端到端 P90 | TTFT P50 | Standard/Fast 端到端加速 |
|---|---|---|---|---|---|
| Sol | Standard | 307.09 s | 308.11 s | 132.37 s | — |
| Sol | Fast | 193.96 s | 231.76 s | 80.42 s | 1.58× |
| Luna | Standard | 254.68 s | 294.99 s | 74.30 s | — |
| Luna | Fast | 239.57 s | 244.44 s | 119.22 s | 1.06× |
Sol 的 Fast 同时改善 TTFT 与持续输出,所以端到端 P50 从 307.09 秒降到 193.96 秒。Luna Fast 虽然持续输出快了约 50%,TTFT P50 却从 74.30 秒升到 119.22 秒,最终总耗时只改善约 6%。这说明本轮 Luna 的首段等待主要受请求级条件影响,不能拿一次端到端总秒数代替模型解码速度。
原始事件还记录了多轮 request timed out、stream reconnect,以及从 WebSocket 回退到 HTTPS。日志时间位置表明,这些传输层重试很可能解释了一部分 30–125 秒 TTFT 波动;但客户端看不到服务端内部状态,所以这只是有证据支持的推断,而不是已证明的唯一原因。
10K 输入为何失效
输入测试用短提示与长提示的响应时间差估计处理速度。短提示本地计数约 397 token,长提示约 10,000 token;服务端 usage 还包含固定系统上下文,所以模型实际 usage 输入更大,但每组长短差都保持 9,603 token。
理论代理公式是:
1 | R_prefill_proxy = (input_long - input_short) / (response_long - response_short) |
只有当长输入稳定地比短输入多花时间时,分母才有可解释意义。本轮结果如下:
| 模型 | 模式 | 短输入 usage P50 | 长输入 usage P50 | 输入差 | 短输入 P50 | 长输入 P50 | 结论 |
|---|---|---|---|---|---|---|---|
| Sol | Standard | 21,954 | 31,557 | 9,603 | 118.63 s | 29.18 s | 不可识别 |
| Sol | Fast | 21,954 | 31,557 | 9,603 | 119.07 s | 27.33 s | 不可识别 |
| Luna | Standard | 17,993 | 27,596 | 9,603 | 28.50 s | 27.28 s | 不可识别 |
| Luna | Fast | 17,993 | 27,596 | 9,603 | 118.65 s | 118.39 s | 不可识别 |
所有分母都非正数。造成失效的可观测因素至少有三类:
- 连接重试:24/24 个输入样本的客户端错误文本都记录了 WebSocket 超时并回退到 HTTPS,响应集中在约 25–31 秒或 117–119 秒两个台阶。
- 缓存不一致:输入测试总体缓存比例为 17.6%,不同样本的 cached input tokens 不同,无法把差值视为同一种输入工作量。
- 固定上下文较大:约 397 token 的用户短提示对应 Luna 17,993、Sol 21,954 个 usage 输入 token,用户输入差只占完整请求的一部分。
如何复测输入
下一轮应把输入 prefill 单独作为实验,而不是继续增加同样噪声下的重复次数:
- 先修传输路径:确保 WebSocket 或 HTTPS 只走一种稳定路径,消除固定超时回退台阶。
- 控制缓存状态:分别设计全未缓存与可控前缀缓存测试,不把两种样本混在同一组。
- 采用配对交错:每组按
short → long → long → short的 ABBA 顺序执行,用相邻配对减弱时间漂移。 - 扩大输入梯度:至少使用 1K、10K、50K 三个输入点,检查延迟是否随 uncached input tokens 单调变化;只有拟合残差可接受时才报告斜率。
1 | for each model × tier: |
这段伪代码的重点是预先定义拒绝条件:如果传输仍重试、缓存不可控、斜率非正或残差过大,就继续报告“未识别”,不从异常值里挑一个有利结果。
选择建议
- 长文本生成优先:在本轮条件下,Fast 的流式收益约 50%,明显大于 Sol/Luna 的 3%–6% 差异。
- 能力优先:先按官方定位和真实任务质量选择 Sol/Luna,再把速度作为次级指标;本文没有质量 eval,不能用 tok/s 代替正确率。
- 成本优先:Luna 是官方面向成本敏感、高吞吐场景的选择;但 Codex 产品用量与公开 API 美元价格不是同一个计费合同,本文不做虚假换算。
- 交互延迟优先:重点复测 TTFT 和传输稳定性。Fast 提高持续输出速度,不保证连接建立、排队和首段等待同步改善。
最终可以把这次结果概括为一句话:Fast 稳定提高了 10K 持续输出吞吐,Sol 只比 Luna 略快;端到端体验仍被 TTFT 与连接重试主导,而 10K 输入速度需要在更稳定的传输与缓存控制下重测。
参考资料
- OpenAI, GPT-5.6 Sol Model.
- OpenAI, GPT-5.6 Luna Model.
- OpenAI, GPT-5.6 Model Guidance.
- 本次公开原始样本:
obsidian-vault/.raw/codex-model-speed-benchmark-2026-08-12/。
Codex Model Speed Benchmark
http://icarus.shaojiemike.top/2026/08/12/Work/0-Digital Worker/Codex-Model-Speed-Benchmark/